home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / MPW_TOOL / TOOLS / TOOLS_WI / ICON_8 / ICONX_FO / LSCAN.C < prev    next >
Text File  |  1990-03-02  |  4KB  |  198 lines

  1. /*
  2.  * File: lscan.c
  3.  *  Contents: bscan, escan
  4.  */
  5.  
  6. #include "::h:config.h"
  7. #include "::h:rt.h"
  8. #include "rproto.h"
  9.  
  10. #ifdef PreProcess
  11. /* include(../M4/lib.m4) /* */
  12. /* */
  13. #endif                    /* PreProcess */
  14.  
  15. /*
  16.  * bscan - set &subject and &pos upon entry to a scanning expression.
  17.  *
  18.  *  Arguments are:
  19.  *    Arg0 - new value for &subject
  20.  *    Arg1 - saved value of &subject
  21.  *    Arg2 - saved value of &pos
  22.  *
  23.  * A variable pointing to the saved &subject and &pos is returned to be
  24.  *  used by escan.
  25.  */
  26.  
  27. LibDcl(bscan,2,"?")
  28.    {
  29.    char sbuf[MaxCvtLen];
  30.    int rc;
  31.    struct pf_marker *cur_pfp;
  32.  
  33. #if MACINTOSH
  34. #if MPW
  35. /* #pragma unused(nargs) */
  36. #endif                    /* MPW */
  37. #endif                    /* MACINTOSH */
  38.  
  39.    /*
  40.     * Convert the new value for &subject to a string.
  41.     */
  42.    if (DeRef(Arg0) == Error) 
  43.       RunErr(0, NULL);
  44.  
  45.    switch (cvstr(&Arg0, sbuf)) {
  46.       case Cvt:
  47.      /*
  48.       * The new value for &subject wasn't a string.  Allocate the
  49.       *  new value and fall through.
  50.       */
  51.          if (strreq(StrLen(Arg0)) == Error) 
  52.             RunErr(0, NULL);
  53.      StrLoc(Arg0) = alcstr(StrLoc(Arg0), StrLen(Arg0));
  54.  
  55.       case NoCvt:
  56.      /*
  57.       * Establish a new &subject value and set &pos to 1.
  58.       */
  59.      k_subject = Arg0;
  60.      k_pos = 1;
  61.          break;
  62.  
  63.       default:
  64.          RunErr(103, &Arg0);
  65.       }
  66.  
  67.    /* If the saved scanning environment belongs to the current procedure
  68.     *  call, put a reference to it in the procedure frame.
  69.     */
  70.    if (pfp->pf_scan == NULL)
  71.       pfp->pf_scan = &Arg1;
  72.    cur_pfp = pfp;
  73.  
  74.    /*
  75.     * Suspend with a variable pointing to the saved &subject and &pos.
  76.     */
  77.    ArgType(0) = D_Var;
  78.    VarLoc(Arg0) = &Arg1;
  79.  
  80.    rc = interp(G_Csusp,cargp);
  81.  
  82.    if (pfp != cur_pfp)
  83.       return rc;
  84.  
  85.    /*
  86.     * Leaving scanning environment. Restore the old &subject and &pos values.
  87.     */
  88.    k_subject = Arg1;
  89.    k_pos = IntVal(Arg2);
  90.    if (pfp->pf_scan == &Arg1)
  91.       pfp->pf_scan = NULL;
  92.  
  93.    if (rc == A_Resumption)
  94.       return A_Failure;
  95.    else
  96.       return rc;
  97.  
  98.    }
  99.  
  100.  
  101. /*
  102.  * escan - restore &subject and &pos at the end of a scanning expression.
  103.  *
  104.  *  Arguments:
  105.  *    Arg0 - variable pointing to old values of &subject and &pos
  106.  *    Arg1 - result of the scanning expression
  107.  *
  108.  * The two arguments are reversed, so that the result of the scanning
  109.  *  expression becomes the result of escan. This result is dereferenced
  110.  *  if it refers to &subject or &pos. Then the saved values of &subject
  111.  *  and &pos are exchanged with the current ones.
  112.  *
  113.  * Escan suspends once it has restored the old &subject; on failure
  114.  *  the new &subject and &pos are "unrestored", and the failure is
  115.  *  propagated into the using clause.
  116.  */
  117.  
  118. LibDcl(escan,1,"escan")
  119.    {
  120.    struct descrip tmp;
  121.    int rc;
  122.    struct pf_marker *cur_pfp;
  123.  
  124. #if MACINTOSH
  125. #if MPW
  126. /* #pragma unused(nargs) */
  127. #endif                    /* MPW */
  128. #endif                    /* MACINTOSH */
  129.  
  130.    /*
  131.     * Copy the result of the scanning expression into Arg0, which will
  132.     *  be the result of the scan.
  133.     */
  134.    tmp = Arg0;
  135.    Arg0 = Arg1;
  136.    Arg1 = tmp;
  137.  
  138.    /*
  139.     * If the result of the scanning expression is &subject or &pos,
  140.     *  it is dereferenced.
  141.     */
  142.    if (((char *)BlkLoc(Arg0) == (char *)&tvky_sub) ||
  143.       ((char *)BlkLoc(Arg0) == (char *)&tvky_pos))
  144.          if (DeRef(Arg0) == Error) 
  145.             RunErr(0, NULL);
  146.  
  147.    /*
  148.     * Swap new and old values of &subject
  149.     */
  150.    tmp = k_subject;
  151.    k_subject = *VarLoc(Arg1);
  152.    *VarLoc(Arg1) = tmp;
  153.  
  154.    /*
  155.     * Swap new and old values of &pos
  156.     */
  157.    tmp = *(VarLoc(Arg1) + 1);
  158.    IntVal(*(VarLoc(Arg1) + 1)) = k_pos;
  159.    k_pos = IntVal(tmp);
  160.  
  161.    /*
  162.     * If we are returning to the scanning environment of the current 
  163.     *  procedure call, indicate that it is no longed in a saved state.
  164.     */
  165.    if (pfp->pf_scan == VarLoc(Arg1))
  166.       pfp->pf_scan = NULL;
  167.    cur_pfp = pfp;
  168.  
  169.    /*
  170.     * Suspend the value of the scanning expression.
  171.     */
  172.  
  173.    rc = interp(G_Csusp,cargp);
  174.  
  175.    if (pfp != cur_pfp)
  176.       return rc;
  177.  
  178.    /*
  179.     * Re-entering scanning environment, exchange the values of &subject
  180.     *  and &pos again
  181.     */
  182.    tmp = k_subject;
  183.    k_subject = *VarLoc(Arg1);
  184.    *VarLoc(Arg1) = tmp;
  185.  
  186.    tmp = *(VarLoc(Arg1) + 1);
  187.    IntVal(*(VarLoc(Arg1) +1)) = k_pos;
  188.    k_pos = IntVal(tmp);
  189.  
  190.    if (pfp->pf_scan == NULL)
  191.       pfp->pf_scan = VarLoc(Arg1);
  192.  
  193.    if (rc == A_Resumption)
  194.       return A_Failure;
  195.    else
  196.       return rc;
  197.    }
  198.